package com.dynamicthreadpool.core;

import com.dynamicthreadpool.factory.ThreadFactoryFactory;
import com.dynamicthreadpool.spi.DynamicThreadFactory;
import com.dynamicthreadpool.strategy.QueueStrategyFactory;
import com.dynamicthreadpool.strategy.RejectStrategyFactory;

import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * 动态线程池实现类，支持运行时调整线程池参数
 */
public class DynamicThreadPool extends ThreadPoolExecutor {

    private String poolName;
    private int queueCapacity;

    /**
     * 构造函数
     * @param corePoolSize 核心线程数
     * @param maximumPoolSize 最大线程数
     * @param keepAliveTime 线程保持时间
     * @param unit 时间单位
     * @param queueCapacity 队列容量
     * @param poolName 线程池名称
     * @param rejectPolicyName 拒绝策略名称
     */
    public DynamicThreadPool(int corePoolSize, int maximumPoolSize, long keepAliveTime, 
                           TimeUnit unit, int queueCapacity, String poolName, String rejectPolicyName) {
        super(
                corePoolSize,
                maximumPoolSize,
                keepAliveTime,
                unit,
                createQueue(null, queueCapacity), // 默认为null，使用默认队列策略
                ThreadFactoryFactory.getThreadFactory("named").setName(poolName),
                RejectStrategyFactory.getStrategy(rejectPolicyName)
        );
        this.poolName = poolName;
        this.queueCapacity = queueCapacity;
    }
    
    /**
     * 构造函数（兼容旧版本）
     * @param corePoolSize 核心线程数
     * @param maximumPoolSize 最大线程数
     * @param keepAliveTime 线程保持时间
     * @param unit 时间单位
     * @param queueCapacity 队列容量
     * @param queueType 队列类型（已废弃，不再使用）
     * @param poolName 线程池名称
     * @param rejectPolicyName 拒绝策略名称
     */
    @Deprecated
    public DynamicThreadPool(int corePoolSize, int maximumPoolSize, long keepAliveTime, 
                           TimeUnit unit, int queueCapacity, String queueType, String poolName, String rejectPolicyName) {
        this(corePoolSize, maximumPoolSize, keepAliveTime, unit, queueCapacity, poolName, rejectPolicyName);
    }

    /**
     * 创建队列
     * @param queueType 队列类型
     * @param capacity 队列容量
     * @return 可调整大小的阻塞队列实例
     */
    private static BlockingQueue<Runnable> createQueue(String queueType, int capacity) {
        if (queueType != null) {
            // 创建URL对象并设置queueType参数
            com.dynamicthreadpool.spi.URL url = new com.dynamicthreadpool.spi.URL("dynamic", "localhost", 0);
            url.setParameter("queueType", queueType);
            return QueueStrategyFactory.createQueue(url, capacity);
        }
        // 如果没有指定队列类型，使用默认队列策略
        return QueueStrategyFactory.createQueue(capacity);
    }

    /**
     * 动态调整核心线程数
     * @param corePoolSize 新的核心线程数
     */
    public synchronized void setCorePoolSize(int corePoolSize) {
        if (corePoolSize >= 0) {
            super.setCorePoolSize(corePoolSize);
        }
    }

    /**
     * 动态调整最大线程数
     * @param maximumPoolSize 新的最大线程数
     */
    public synchronized void setMaximumPoolSize(int maximumPoolSize) {
        if (maximumPoolSize >= getCorePoolSize()) {
            super.setMaximumPoolSize(maximumPoolSize);
        }
    }

    /**
     * 动态调整线程保持时间
     * @param time 新的保持时间
     * @param unit 时间单位
     */
    public synchronized void setKeepAliveTime(long time, TimeUnit unit) {
        if (time >= 0) {
            super.setKeepAliveTime(time, unit);
        }
    }

    /**
     * 动态调整线程池名称
     * @param poolName 新的线程池名称
     */
    public synchronized void setPoolName(String poolName) {
        if (poolName != null && !poolName.isEmpty()) {
            this.poolName = poolName;
            // 注意：修改线程工厂并不会影响已创建的线程，只会影响新创建的线程
            setThreadFactory(ThreadFactoryFactory.getThreadFactory("named").setName(poolName));
        }
    }

    /**
     * 动态调整拒绝策略
     * @param rejectPolicyName 拒绝策略名称
     */
    public synchronized void setRejectPolicy(String rejectPolicyName) {
        setRejectedExecutionHandler(RejectStrategyFactory.getStrategy(rejectPolicyName));
    }

    /**
     * 动态调整队列容量
     * @param queueCapacity 新的队列容量
     * @return 是否调整成功
     */
    public synchronized boolean setQueueCapacity(int queueCapacity) {
        if (queueCapacity <= 0) {
            throw new IllegalArgumentException("Queue capacity must be greater than 0");
        }
        
        this.queueCapacity = queueCapacity;
        
        // 获取当前队列
        BlockingQueue<Runnable> queue = getQueue();
        
        // 如果队列支持动态调整大小
        if (queue instanceof ResizeableBlockingQueue) {
            boolean result = ((ResizeableBlockingQueue<Runnable>) queue).resize(queueCapacity);
            if (result) {
                System.out.println("Queue capacity changed to: " + queueCapacity);
            }
            return result;
        } else {
            // 对于不支持动态调整大小的队列，打印警告信息
            System.out.println("Warning: Current queue type does not support dynamic resizing. Capacity updated but no actual change applied.");
            return false;
        }
    }
    


    /**
     * 获取线程池名称
     * @return 线程池名称
     */
    public String getPoolName() {
        return poolName;
    }

    /**
     * 获取队列类型（已废弃，不再使用）
     * @return 固定返回ResizeableArrayBlockingQueue
     */
    @Deprecated
    public String getQueueType() {
        return "ResizeableArrayBlockingQueue";
    }

    /**
     * 获取队列容量
     * @return 队列容量
     */
    public int getQueueCapacity() {
        return queueCapacity;
    }

    @Override
    public String toString() {
        return "DynamicThreadPool{" +
                "poolName='" + poolName + '\'' +
                ", corePoolSize=" + getCorePoolSize() +
                ", maximumPoolSize=" + getMaximumPoolSize() +
                ", keepAliveTime=" + getKeepAliveTime(TimeUnit.MILLISECONDS) + "ms" +
                ", queueCapacity=" + queueCapacity +
                ", activeCount=" + getActiveCount() +
                ", taskCount=" + getTaskCount() +
                ", completedTaskCount=" + getCompletedTaskCount() +
                '}';
    }
}
